package com.chuangshixinchen.enterprise.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chuangshixinchen.enterprise.common.DateUtil;
import com.chuangshixinchen.enterprise.common.Result;
import com.chuangshixinchen.enterprise.common.StatusCode;
import com.chuangshixinchen.enterprise.entity.Tb_declaration_flow;
import com.chuangshixinchen.enterprise.entity.Tb_enterprise;
import com.chuangshixinchen.enterprise.entity.Tb_staff;
import com.chuangshixinchen.enterprise.entity.excel.StaffInData;
import com.chuangshixinchen.enterprise.entity.excel.StaffInExcelListener;
import com.chuangshixinchen.enterprise.entity.excel.StaffOutData;
import com.chuangshixinchen.enterprise.entity.excel.StaffOutExcelListener;
import com.chuangshixinchen.enterprise.mapper.Tb_declaration_flowMapper;
import com.chuangshixinchen.enterprise.mapper.Tb_enterpriseMapper;
import com.chuangshixinchen.enterprise.mapper.Tb_staffMapper;
import com.chuangshixinchen.enterprise.service.ITb_declaration_flowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chuangshixinchen.enterprise.vo.req.DeclarationFlowReqPageVo;
import com.chuangshixinchen.enterprise.vo.res.DeclarationFlowResVo;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2021-08-16
 */
@Service
public class Tb_declaration_flowServiceImpl extends ServiceImpl<Tb_declaration_flowMapper, Tb_declaration_flow> implements ITb_declaration_flowService {

    @Value("${enterprise.file.root.path}")
    private String fileRootPath;

    private static String BASE_URL = "http://image.szhtj.cn/";

    private static final List<String> CONTENT_TYPES = Arrays.asList("application/vnd.ms-excel"
            ,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            ,"application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document");

    private String errorStr = "文件类型不正确或格式错误";

    @Resource
    private Tb_staffMapper staffMapper;
    @Resource
    private Tb_enterpriseMapper enterpriseMapper;

    @Override
    public Result<Page<DeclarationFlowResVo>> listPage(DeclarationFlowReqPageVo vo) {
        Page<Tb_declaration_flow> page = new Page<>(vo.getPageNum(), vo.getPageSize());
        LambdaQueryWrapper<Tb_declaration_flow> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasLength(vo.getUnitNumber())){
            wrapper.eq(Tb_declaration_flow::getUnitNumber, vo.getUnitNumber());
        }
        if (StringUtils.hasLength(vo.getUnitName())){
            wrapper.like(Tb_declaration_flow::getUnitName,vo.getUnitName());
        }
        if (vo.getStartTime()!=null){
            wrapper.ge(Tb_declaration_flow::getCreateTime,vo.getStartTime());
        }
        if (vo.getEndTime()!=null){
            wrapper.le(Tb_declaration_flow::getCreateTime,vo.getEndTime());
        }
        if (vo.getDeclarationType()!=null){
            wrapper.eq(Tb_declaration_flow::getDeclarationType,vo.getDeclarationType());
        }
        wrapper.orderByDesc(Tb_declaration_flow::getId);
        Page<Tb_declaration_flow> declarationFlowPage = baseMapper.selectPage(page, wrapper);
        Page<DeclarationFlowResVo> pageRes = new Page<>(vo.getPageNum(), vo.getPageSize());
        pageRes.setTotal(declarationFlowPage.getTotal());
        pageRes.setCurrent(declarationFlowPage.getCurrent());
        pageRes.setOrders(declarationFlowPage.getOrders());
        pageRes.setSize(declarationFlowPage.getSize());
        pageRes.setPages(declarationFlowPage.getPages());

//        pageRes.setRecords(declarationFlowPage.getRecords());
        List<DeclarationFlowResVo> recordResList = new ArrayList<>();
        DeclarationFlowResVo recordRes = null;
        String tempUnitNumber = "";
        for (int i = 0; i < declarationFlowPage.getRecords().size(); i++) {
            Tb_declaration_flow record = declarationFlowPage.getRecords().get(i);
            recordRes = new DeclarationFlowResVo();
            recordRes.setAttachment1(record.getAttachment1());
            recordRes.setAttachment2(record.getAttachment2());
            recordRes.setUpdateTime(record.getUpdateTime());
            recordRes.setUnitNumber(record.getUnitNumber());
            recordRes.setUnitName(record.getUnitName());
            recordRes.setUnitAddress(record.getUnitAddress());
            recordRes.setId(record.getId());
            recordRes.setDeclarationType(record.getDeclarationType());
            recordRes.setCreateTime(record.getCreateTime());
            recordRes.setArea(record.getArea());
            recordRes.setApplicantPhone(record.getApplicantPhone());
            recordRes.setApplicant(record.getApplicant());
            if (vo.getStartTime()!=null){
                //查询最近的录用和退工记录
                LambdaQueryWrapper<Tb_declaration_flow> wrapperInOut = new LambdaQueryWrapper<>();
                wrapperInOut
                        .eq(Tb_declaration_flow::getUnitNumber,record.getUnitNumber())
                        .eq(Tb_declaration_flow::getDeclarationType,record.getDeclarationType())
                        .le(Tb_declaration_flow::getCreateTime,vo.getStartTime())
                        .orderByDesc(Tb_declaration_flow::getCreateTime);
                List<Tb_declaration_flow> declarationFlowInOutList = baseMapper.selectList(wrapperInOut);
                //如果查询列表不为空，且单位编号不是之前编号，则进行赋值
                if (declarationFlowInOutList.size()>0&&!tempUnitNumber.contentEquals(record.getUnitNumber())){
                    if (record.getDeclarationType()==0){
                        recordRes.setNearOutTime(declarationFlowInOutList.get(0).getCreateTime());
                    }else {
                        recordRes.setNearInTime(declarationFlowInOutList.get(0).getCreateTime());
                    }
                    tempUnitNumber = record.getUnitNumber();
                }
            }

            recordResList.add(recordRes);
        }
        pageRes.setRecords(recordResList);
        return new Result<>(true, StatusCode.OK,"查询成功",pageRes);
    }

    @Override
    public Result<Tb_declaration_flow> getInfo(Long id) {
        Tb_declaration_flow declarationFlow = baseMapper.selectById(id);
        if (declarationFlow==null){
            return new Result<Tb_declaration_flow>(false,StatusCode.ERROR,"无此用户");
        }
        return new Result<Tb_declaration_flow>(true,StatusCode.OK,"查询成功",declarationFlow);
    }

    @Override
    @Transactional
    public Result saveInfo(MultipartFile deFile,MultipartFile prFile, ITb_declaration_flowService declarationFlowService, Tb_declaration_flow declarationFlow) {
        Date dateNow = new Date();
        //退工，在20211004之后不允许
        long differentTimestamp = DateUtil.getDifferentTimestamp(dateNow, DateUtil.stringToTime("2021-10-03 23:59:59"));
        if (differentTimestamp<0&&declarationFlow.getDeclarationType()==0){
            return new Result(false,StatusCode.ERROR,"2021-10-04后无法录入退工！");
        }
        int changeNum = 0;
        //添加流水表数据,先插入流水表，用于获取flowId
        changeNum = baseMapper.insert(declarationFlow);
        System.out.println(declarationFlow);
        //添加到企业表
        //查询是否有该企业信息
        LambdaQueryWrapper<Tb_enterprise> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Tb_enterprise::getUnitNumber,declarationFlow.getUnitNumber());
        Tb_enterprise enterprise = enterpriseMapper.selectOne(wrapper);

        Tb_enterprise enterpriseNew = new Tb_enterprise();
        enterpriseNew.setArea(declarationFlow.getArea());
        enterpriseNew.setUnitAddress(declarationFlow.getUnitAddress());
        enterpriseNew.setUnitName(declarationFlow.getUnitName());
        enterpriseNew.setUnitNumber(declarationFlow.getUnitNumber());
        if (enterprise==null){
            //查询企业信息为空，说明之前无该企业信息，则新增企业信息
            enterpriseMapper.insert(enterpriseNew);
        }else {
            //查询有企业信息，则也就行更新操作
            enterpriseMapper.update(enterpriseNew,wrapper);//根据企业编号更新企业数据
        }
        //处理文件
        try{
            String deOriginalFileName = deFile.getOriginalFilename();
            //校验文件类型
            String contentType = deFile.getContentType();
            if (!CONTENT_TYPES.contains(contentType)){
                System.out.println("文件类型不合法："+deOriginalFileName+")");
                return new Result(false, StatusCode.ERROR,"文件类型不合法！");
            }

            InputStream inputStream = deFile.getInputStream();
            if (declarationFlow.getDeclarationType()==0){//退工
                EasyExcel.read(inputStream, StaffOutData.class,new StaffOutExcelListener(declarationFlow,declarationFlowService)).sheet()
                        .headRowNumber(2)
                        .doRead();
            }else {//录用
                EasyExcel.read(inputStream,StaffInData.class,new StaffInExcelListener(declarationFlow,declarationFlowService)).sheet()
                        .headRowNumber(5)
                        .doRead();
            }

            //保存deFile
            String datePath = new SimpleDateFormat("yyyyMMdd").format(dateNow);
            String timePath = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(dateNow);
//            String wholePath = fileRootPath + datePath + File.separator;
            String wholePath = fileRootPath + datePath + File.separator + (declarationFlow.getDeclarationType()==0?"退工":"录用") + File.separator;
//            String deNewFileName= UUID.randomUUID().toString().replace("-","")+"."+FilenameUtils.getExtension(deOriginalFileName);
            String deNewFileName= declarationFlow.getUnitName() + "-" + declarationFlow.getUnitNumber() + "-" + (declarationFlow.getDeclarationType()==0?"退工花名册":"录用花名册") + "-" + timePath +"."+FilenameUtils.getExtension(deOriginalFileName);

            File newFile = new File(wholePath + deNewFileName);
            if (!newFile.exists()){
                newFile.mkdirs();
            }
            deFile.transferTo(newFile);
//            System.out.println(BASE_URL + datePath + "/" + deNewFileName);
            //更新流水表两个附件链接
            declarationFlow.setAttachment1(BASE_URL + datePath + File.separator + (declarationFlow.getDeclarationType()==0?"退工":"录用") + File.separator + deNewFileName);

            //保存prFile
//            String prWholePath = fileRootPath + datePath + File.separator;
            String prWholePath = fileRootPath + datePath + File.separator + (declarationFlow.getDeclarationType()==0?"退工":"录用") + File.separator;

            String prOriginalFileName = prFile.getOriginalFilename();
//            String prNewFileName= UUID.randomUUID().toString().replace("-","")+"."+FilenameUtils.getExtension(prOriginalFileName);
            String prNewFileName= declarationFlow.getUnitName() + "-" + declarationFlow.getUnitNumber() + "-" + (declarationFlow.getDeclarationType()==0?"退工承诺书":"录用承诺书") + "-" + timePath +"."+FilenameUtils.getExtension(prOriginalFileName);

            File prNewFile = new File(prWholePath + prNewFileName);
            if (!prNewFile.exists()){
                prNewFile.mkdirs();
            }
            prFile.transferTo(prNewFile);
//            System.out.println(BASE_URL + datePath + "/" + prNewFileName);
            //更新流水表两个附件链接
            declarationFlow.setAttachment2(BASE_URL + datePath + File.separator + (declarationFlow.getDeclarationType()==0?"退工":"录用") + File.separator + prNewFileName);
            changeNum = baseMapper.updateById(declarationFlow);
        } catch (Exception e) {
            e.printStackTrace();
            //手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new Result(false,StatusCode.ERROR,errorStr);
        }
        if (changeNum==0){
            return new Result(false, StatusCode.ERROR,"提交失败");
        }
        return new Result(true,StatusCode.OK,"添加成功");
    }

    @Override
    @Transactional
    public void saveStaffIn4Excel(Tb_declaration_flow declarationFlow, List<StaffInData> staffInDataList) {
//        System.out.println("****");
//        System.out.println(staffInDataList);
        //插入员工录入表
        for (int i = 0; i < staffInDataList.size(); i++) {
            StaffInData staffInData = staffInDataList.get(i);
            if ((!StringUtils.hasLength(staffInData.getIdCard()))||(!StringUtils.hasLength(staffInData.getName()))){
                //身份证或名字为空，不进行插入
                continue;
            }
            Tb_staff staff = new Tb_staff();

            errorStr = "身份证格式不正确，应为18位";
            if (staffInData.getIdCard().length()!=18){
                int testNum = 1/0;//故意出错跳出循环体
            }
            errorStr = "合同起始日期格式不正确，应为如：“20210920”";
            if (staffInData.getContractStartTime().length()!=8){
                int testNum = 1/0;//故意出错跳出循环体
            }
            staff.setContractStartTime(StringUtils.hasLength(staffInData.getContractStartTime())?DateUtil.stringToTime(staffInData.getContractStartTime(),"yyyyMMdd"):null);
            errorStr = "合同结束日期格式不正确，应为如：“20210920”";
            if (staffInData.getContractEndTime().length()!=8){
                int testNum = 1/0;//故意出错跳出循环体
            }
            staff.setContractEndTime(StringUtils.hasLength(staffInData.getContractEndTime())?DateUtil.stringToTime(staffInData.getContractEndTime(),"yyyyMMdd"):null);
            errorStr = "月缴费工资格式不正确，不能有数字以外的字符出现！";
            staff.setSalary(StringUtils.hasLength(staffInData.getSalary())?(Integer.parseInt(staffInData.getSalary())*100):0);
            errorStr = "合同类型格式错误";
            if (staffInData.getContractType().indexOf(".")==-1){
                int testNum = 1/0;//故意出错跳出循环体
            }
            staff.setContractType(StringUtils.hasLength(staffInData.getContractType())?staffInData.getContractType().substring(staffInData.getContractType().indexOf(".")+1):staffInData.getContractType());
            errorStr = "新增原因格式错误";
            if (staffInData.getIncreaseReason().indexOf(".")==-1){
                int testNum = 1/0;//故意出错跳出循环体
            }
            staff.setIncreaseReason(StringUtils.hasLength(staffInData.getIncreaseReason())?staffInData.getIncreaseReason().substring(staffInData.getIncreaseReason().indexOf(".")+1):staffInData.getIncreaseReason());
            errorStr = "从事岗位格式错误";
            if (staffInData.getPost().indexOf(".")==-1){
                int testNum = 1/0;//故意出错跳出循环体
            }
            staff.setPost(StringUtils.hasLength(staffInData.getPost())?staffInData.getPost().substring(staffInData.getPost().indexOf(".")+1):staffInData.getPost());
            errorStr = "用工类型格式错误";
            if (staffInData.getWorkType().indexOf(".")==-1){
                int testNum = 1/0;//故意出错跳出循环体
            }
            staff.setWorkType(StringUtils.hasLength(staffInData.getWorkType())?staffInData.getWorkType().substring(staffInData.getWorkType().indexOf(".")+1):staffInData.getWorkType());
            errorStr = "文件类型不正确或格式错误";
            staff.setArea(declarationFlow.getArea());
            staff.setDeclarationType(1);
            staff.setFlowId(declarationFlow.getId());
            staff.setIdCard(staffInData.getIdCard());
            staff.setName(staffInData.getName());
            staff.setUnitAddress(declarationFlow.getUnitAddress());
            staff.setUnitName(declarationFlow.getUnitName());
            staff.setUnitNumber(declarationFlow.getUnitNumber());
            staffMapper.insert(staff);
        }
    }

    @Override
    @Transactional
    public void saveStaffOut4Excel(Tb_declaration_flow declarationFlow, List<StaffOutData> staffOutDataList) {
        //插入员工录入表
        for (int i = 0; i < staffOutDataList.size(); i++) {
            StaffOutData staffOutData = staffOutDataList.get(i);
            if ((!StringUtils.hasLength(staffOutData.getIdCard()))||(!StringUtils.hasLength(staffOutData.getName()))){
                //身份证或名字为空，不进行插入
                continue;
            }
            Tb_staff staff = new Tb_staff();
            errorStr = "身份证格式不正确，应为18位";
            if (staffOutData.getIdCard().length()!=18){
                int testNum = 1/0;//故意出错跳出循环体
            }
            errorStr = "退工日期格式不正确";
            if (staffOutData.getQuitTime().length()!=8){
                int testNum = 1/0;//故意出错跳出循环体
            }
            staff.setQuitTime(StringUtils.hasLength(staffOutData.getQuitTime())?DateUtil.stringToTime(staffOutData.getQuitTime(),"yyyyMMdd"):null);
            errorStr = "退工原因格式不正确";
            if (staffOutData.getQuitReason().indexOf(".")==-1){
                int testNum = 1/0;//故意出错跳出循环体
            }
            staff.setQuitReason(StringUtils.hasLength(staffOutData.getQuitReason())?staffOutData.getQuitReason().substring(staffOutData.getQuitReason().indexOf(".")+1):staffOutData.getQuitReason());
            errorStr = "文件类型不正确或格式错误";
            staff.setArea(declarationFlow.getArea());
            staff.setDeclarationType(0);//退工
            staff.setFlowId(declarationFlow.getId());
            staff.setIdCard(staffOutData.getIdCard());
            staff.setName(staffOutData.getName());
            staff.setUnitAddress(declarationFlow.getUnitAddress());
            staff.setUnitName(declarationFlow.getUnitName());
            staff.setUnitNumber(declarationFlow.getUnitNumber());
            staff.setRemark(staffOutData.getRemark());
            staffMapper.insert(staff);
        }
    }

    @Override
    @Transactional
    public Result removeInfo(String ids) {
        List<Long> idList = new ArrayList<>();
        List<String> idsStr = Arrays.asList(ids.split(","));
        for (int i = 0; i < idsStr.size(); i++) {
            Long flowId = Long.parseLong(idsStr.get(i));
            idList.add(flowId);
            //删除流失所对应的员工信息
            LambdaQueryWrapper<Tb_staff> wrapper = new LambdaQueryWrapper();
            wrapper.eq(Tb_staff::getFlowId,flowId);
            staffMapper.delete(wrapper);
        }
        int changeNum = baseMapper.deleteBatchIds(idList);
        if (changeNum==0){
            return new Result(false,StatusCode.ERROR,"删除失败");
        }
        return new Result(true,StatusCode.OK,"删除成功");
    }
}
